package com.av.db.layer.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.av.db.dataobjects.ElementoCatalogo;
import com.av.db.dataobjects.enums.Catalogo;
import com.av.db.layer.interfaces.ElementoCatalogoLayer;
import com.av.exceptions.AvException;

/**
 * Clase que contiene la implementacion de funciones para la tabla de
 * elementoCatalogo utilizando la tecnologia de Hibernate
 * 
 * @author Emmanuel Alcantara Garces
 * 
 */

public class ElementoCatalogoLayerImpl extends HibernateDaoSupport implements
		ElementoCatalogoLayer {

	private static Logger log = Logger
			.getLogger(ElementoCatalogoLayerImpl.class);

	/**
	 * Funcion que actualiza en la base de datos un elemento de catalogo en
	 * especifico
	 */
	@Override
	public void actualizar(ElementoCatalogo elementoCatalogo)
			throws AvException {
		log.info("Inicio - actualizar(ElementoCatalogo elementoCatalogo)");
		log.debug(elementoCatalogo.toString());

		if (elementoCatalogo == null) {
			log.error("No se puede actualizar un elemento de catalogo nulo");
			throw new AvException("Elemento de catalogo nulo a ser actualizado");
		}

		if (elementoCatalogo.getId() < 0) {
			log
					.error("No se puede actualizar un elemento de catalogo con identificador "
							+ "invalido");
			throw new AvException(
					"Elemento de catalogo con identificador invalido a ser "
							+ "actualizado");
		}

		getHibernateTemplate().update(elementoCatalogo);

		log.info("Fin - actualizar(ElementoCatalogo elementoCatalogo)");
	}// actualizar

	/**
	 * Funcion que agrega en la base de datos configurada un nuevo elemento de
	 * catalogo
	 */
	@Override
	public void agregar(ElementoCatalogo elementoCatalogo) throws AvException {
		log.info("Inicio - agregar(ElementoCatalogo elementoCatalogo)");
		log.debug(elementoCatalogo.toString());

		if (elementoCatalogo == null) {
			log.error("No se puede agregar un elemento de catalogo nulo");
			throw new AvException("Elemento de catalogo nulo a ser agregado");
		}

		getHibernateTemplate().save(elementoCatalogo);

		log.info("Fin - agregar(ElementoCatalogo elementoCatalogo)");
	}// agregar

	/**
	 * Funcion que elimina un elemento de catalogo especifico de la base de
	 * datos configurada
	 */
	@Override
	public void eliminar(ElementoCatalogo elementoCatalogo) throws AvException {
		log.info("Inicio - eliminar(ElementoCatalogo elementoCatalogo)");
		log.debug(elementoCatalogo.toString());

		if (elementoCatalogo == null) {
			log.error("No se puede eliminar un elemento de catalogo nulo");
			throw new AvException("Elemento de catalogo nulo a ser eliminado");
		}

		if (elementoCatalogo.getId() < 0) {
			log
					.error("No se puede eliminar un elemento de catalogo con identificador negativo");
			throw new AvException("Identificador negativo");
		}

		getHibernateTemplate().delete(elementoCatalogo);

		log.info("Fin - eliminar(ElementoCatalogo elementoCatalogo)");
	}// eliminar

	/**
	 * Funcion que obtiene un elemento de catalogo de la base de datos
	 * configurada a partir de su identificador
	 */
	@Override
	public ElementoCatalogo obtener(int id) {
		log.info("Inicio - obtener(int id)");
		log.debug("Id : " + id);

		if (id < 0) {
			log
					.warn("No se puede obtener un elemento de catalogo con identificador negativo");
			return null;
		}

		ElementoCatalogo tmp = getHibernateTemplate().get(
				ElementoCatalogo.class, id);

		if (tmp != null) {
			log.debug("Elemento/Catalogo : " + tmp.toString());
		} else {
			log.debug("Elemento de catalogo no encontrado");
		}

		log.info("Fin - obtener(int id)");

		return tmp;
	}// obtener

	/**
	 * Funcion que obtiene el conjunto de todos los elementos de catalogo
	 * registrados en la base de datos configurada
	 */
	@Override
	public ElementoCatalogo[] obtener() {
		log.info("Inicio - obtener()");

		List<?> l = getSession().createCriteria(ElementoCatalogo.class)
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(ElementoCatalogo.ID)).list();

		ElementoCatalogo[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new ElementoCatalogo[l.size()];
			l.toArray(tmp);
		}

		log.info("Fin - obtener()");

		return tmp;
	}// obtener

	/**
	 * Funcion que obtiene el conjunto de todos los elementos activos de
	 * catalogo registrados en la base de datos configurada para un idCatalogo
	 * especifico
	 */
	@Override
	public ElementoCatalogo[] obtener(Catalogo catalogo) {
		log.info("Inicio - obtenerCatalogo(Catalogo idCatalgo)");
		log.debug("Catalogo : " + catalogo);

		List<?> l = getSession().createCriteria(ElementoCatalogo.class).add(
				Restrictions.eq(ElementoCatalogo.CATALOGO, catalogo)).add(
				Restrictions.eq(ElementoCatalogo.ACTIVO, true))
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(ElementoCatalogo.DESCRIPCION)).list();

		ElementoCatalogo[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new ElementoCatalogo[l.size()];
			l.toArray(tmp);
		}
		log.info("Fin - obtenerCatalogo(Catalogo idCatalgo)");
		return tmp;
	}// obtenerCatalogo

	/**
	 * Funcion que obtiene los elementos activos del catalogo
	 */
	@Override
	public ElementoCatalogo[] obtenerActivos() {
		log.info("Inicio - obtenerActivos()");

		List<?> l = getSession().createCriteria(ElementoCatalogo.class).add(
				Restrictions.eq(ElementoCatalogo.ACTIVO, true))
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(ElementoCatalogo.ID)).list();

		ElementoCatalogo[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new ElementoCatalogo[l.size()];
			l.toArray(tmp);
		}

		log.info("Fin - obtenerActivos()");

		return tmp;
	}// obtenerActivos

	/**
	 * Funcion que obtiene los elementos inactivos del catalogo
	 */
	@Override
	public ElementoCatalogo[] obtenerInactivos() {
		log.info("Inicio - obtenerInactivos()");

		List<?> l = getSession().createCriteria(ElementoCatalogo.class).add(
				Restrictions.eq(ElementoCatalogo.ACTIVO, false))
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(ElementoCatalogo.ID)).list();

		ElementoCatalogo[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new ElementoCatalogo[l.size()];
			l.toArray(tmp);
		}

		log.info("Fin - obtenerInactivos()");

		return tmp;
	}// obtenerInactivos
}// ElementoCatalogoLayerImpl
